{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 第六章 嵌入适配器 Embedding Adaptors"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 目录\n",
    "- [ 6.1 -Embedding Adaptors原理及准备工作](#61-embedding-adaptors原理及准备工作)\n",
    "- [ 6.2 - Creating a dataset（创建数据集）](#62-creating-a-dataset创建数据集)\n",
    "- [ 6.3 - Setting up the model（设置模型）](#63-setting-up-the-model设置模型)\n",
    "- [ 6.4 - 总结](#64-总结)\n",
    "\n",
    "在这一章中，我们将学习使用Embedding Adaptors(嵌入适配器)进行查询结果的增强。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 6.1  Embedding Adaptors原理及准备工作"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![Embedding Adapter.png](./images/Embedding%20Adapter.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "我们通过图片了解 Embedding Adaptors（嵌入适配器）的工作原理：\n",
    "\n",
    "在一个系统中，用户通过应用程序(App)提交一个查询（例如“Revenue Growth”），查询会被发送到大型语言模型（LLM）中。而在检索部分，嵌入模型会根据查询生成嵌入向量，嵌入适配器会对这些嵌入进行进一步处理或转换。最后，系统会基于嵌入向量检索相关文档（例如“Annual Income...”），最终，LLM会使用这些信息来生成答案。\n",
    "\n",
    "Embedding Adaptors（嵌入适配器）是一种改变查询的嵌入，直接为了产生更好的检索结果。\n",
    "\n",
    "我们在检索系统中插入一个额外的阶段，称为嵌入适配器。这发生在嵌入模型之后，但在我们得到最相关的结果之前。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "首先，加载我们需要的辅助函数，为了有效地训练模型，这次我们需要使用`torch`。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "D:\\Anaconda3\\Lib\\site-packages\\umap\\distances.py:1063: NumbaDeprecationWarning: \u001b[1mThe 'nopython' keyword argument was not supplied to the 'numba.jit' decorator. The implicit default value for this argument is currently False, but it will be changed to True in Numba 0.59.0. See https://numba.readthedocs.io/en/stable/reference/deprecation.html#deprecation-of-object-mode-fall-back-behaviour-when-using-jit for details.\u001b[0m\n",
      "  @numba.jit()\n",
      "D:\\Anaconda3\\Lib\\site-packages\\umap\\distances.py:1071: NumbaDeprecationWarning: \u001b[1mThe 'nopython' keyword argument was not supplied to the 'numba.jit' decorator. The implicit default value for this argument is currently False, but it will be changed to True in Numba 0.59.0. See https://numba.readthedocs.io/en/stable/reference/deprecation.html#deprecation-of-object-mode-fall-back-behaviour-when-using-jit for details.\u001b[0m\n",
      "  @numba.jit()\n",
      "D:\\Anaconda3\\Lib\\site-packages\\umap\\distances.py:1086: NumbaDeprecationWarning: \u001b[1mThe 'nopython' keyword argument was not supplied to the 'numba.jit' decorator. The implicit default value for this argument is currently False, but it will be changed to True in Numba 0.59.0. See https://numba.readthedocs.io/en/stable/reference/deprecation.html#deprecation-of-object-mode-fall-back-behaviour-when-using-jit for details.\u001b[0m\n",
      "  @numba.jit()\n",
      "D:\\Anaconda3\\Lib\\site-packages\\umap\\umap_.py:660: NumbaDeprecationWarning: \u001b[1mThe 'nopython' keyword argument was not supplied to the 'numba.jit' decorator. The implicit default value for this argument is currently False, but it will be changed to True in Numba 0.59.0. See https://numba.readthedocs.io/en/stable/reference/deprecation.html#deprecation-of-object-mode-fall-back-behaviour-when-using-jit for details.\u001b[0m\n",
      "  @numba.jit()\n"
     ]
    }
   ],
   "source": [
    "from helper_utils import load_chroma, word_wrap, project_embeddings\n",
    "from chromadb.utils.embedding_functions import SentenceTransformerEmbeddingFunction\n",
    "import numpy as np\n",
    "import umap\n",
    "from tqdm import tqdm\n",
    "\n",
    "import torch"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "生成我们的嵌入函数并将所有内容加载到`chroma_collection`集合中。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1028"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "embedding_function = SentenceTransformerEmbeddingFunction()\n",
    "\n",
    "chroma_collection = load_chroma(filename='./data/2024年北京市政府工作报告.pdf', \\\n",
    "                                collection_name='beijing_annual_report_2024', \\\n",
    "                                embedding_function=embedding_function,\n",
    "                                langcode='zh')  # 注意中文文档将langcode改为'zh'\n",
    "chroma_collection.count()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "投射我们的嵌入数据。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 1028/1028 [21:21<00:00,  1.25s/it] \n"
     ]
    }
   ],
   "source": [
    "embeddings = chroma_collection.get(include=['embeddings'])['embeddings']\n",
    "umap_transform = umap.UMAP(random_state=0, transform_seed=0).fit(embeddings)\n",
    "projected_dataset_embeddings = project_embeddings(embeddings, umap_transform)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "与以前相同，配置`OPENAI_API_KEY`。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "import openai\n",
    "from openai import OpenAI\n",
    "\n",
    "from dotenv import load_dotenv, find_dotenv\n",
    "_ = load_dotenv(find_dotenv()) \n",
    "openai.api_key = os.environ['OPENAI_API_KEY']\n",
    "\n",
    "openai_client = OpenAI()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 6.2 Creating a dataset（创建数据集）"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "与以前相同（增加不同的系统指示）。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "def generate_queries(model=\"gpt-3.5-turbo\"):\n",
    "    messages = [\n",
    "        {\n",
    "            \"role\": \"system\",\n",
    "            # 系统角色消息，它指示模型扮演一个有帮助的、专业的政府年度报告研究助手角色。\n",
    "            # 提供的内容是一个明确的任务描述，要求模型提出10到15个短问题，\n",
    "            # 这些问题在分析年度报告时非常重要。\n",
    "            # 这个指示还特别要求模型不要输出复合问题，即包含多个句子或连接词的问题。\n",
    "            # 同时要求每个问题单独一行，行与行之间用换行符分隔。\n",
    "            \"content\": \"You are a helpful and expert financial research assistant. You help users analyze government work reports to better understand the government. \"\n",
    "            \"Suggest 10 to 15 short questions that are important to ask when analyzing an annual report. \"\n",
    "            \"Do not output any compound questions (questions with multiple sentences or conjunctions).\"\n",
    "            \"Output each question on a separate line divided by a newline.\"\n",
    "            \"Use Chinese\"\n",
    "        },\n",
    "    ]\n",
    "\n",
    "    response = openai_client.chat.completions.create(\n",
    "        model=model,\n",
    "        messages=messages,\n",
    "    )\n",
    "    content = response.choices[0].message.content\n",
    "    content = content.split(\"\\n\")\n",
    "    return content"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用LLM进行生成我们的15个问题。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1. 政府在过去一年中主要实施了哪些经济政策？\n",
      "2. 政府在年度报告中提及的财政支出重点是什么？\n",
      "3. 政府在年度报告中提及的经济增长率是多少？\n",
      "4. 政府在年度报告中是否提及了通货膨胀率？\n",
      "5. 政府在年度报告中提及了哪些重点投资项目？\n",
      "6. 政府在年度报告中是否提及了失业率和就业情况？\n",
      "7. 政府在年度报告中是否提及了社会福利改革和提升？\n",
      "8. 政府在年度报告中是否提及了环境保护和可持续发展？\n",
      "9. 政府在年度报告中是否提及了减少贫困和改善生活水平的措施？\n",
      "10. 政府在年度报告中提及的税收政策有哪些调整？\n",
      "11. 政府在年度报告中是否提及了外贸政策和国际经济合作？\n",
      "12. 政府在年度报告中提及了哪些金融改革和监管举措？\n",
      "13. 政府在年度报告中是否提及了农业发展和农村改革？\n",
      "14. 政府在年度报告中提及的基础设施建设情况如何？\n",
      "15. 政府在年度报告中是否提及了科技创新和人才培养计划？\n"
     ]
    }
   ],
   "source": [
    "generated_queries = generate_queries()\n",
    "for query in generated_queries:\n",
    "    print(query)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "指定返回每个查询的前10个结果，并且要求结果包括相关文档和嵌入向量。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "results = chroma_collection.query(query_texts=generated_queries, n_results=10, include=['documents', 'embeddings'])\n",
    "retrieved_documents = results['documents']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "执行这段代码后，`retrieved_documents`中将包含每个查询问题检索到的文档列表。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "提示模型系统（给定的陈述是否与给定的相关查询）。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "def evaluate_results(query, statement, model=\"gpt-3.5-turbo\"):\n",
    "    messages = [\n",
    "    {\n",
    "        \"role\": \"system\",\n",
    "        # 指示模型扮演一个有用的财务研究助手角色，\n",
    "        # 并要求模型评估给定查询与声明的相关性，只输出\"yes\"或\"no\"。\n",
    "        \"content\": \"You are a helpful expert financial research assistant. You help users analyze financial statements to better understand companies. \"\n",
    "        \"For the given query, evaluate whether the following satement is relevant.\"\n",
    "        \"Output only 'yes' or 'no'.\"\n",
    "    },\n",
    "    {\n",
    "        \"role\": \"user\",\n",
    "        \"content\": f\"Query: {query}, Statement: {statement}\"\n",
    "    }\n",
    "    ]\n",
    "    # 使用OpenAI的chat API发送请求，传递模型名称、消息列表和最大令牌数。\n",
    "    # 最大令牌数设置为1，因为期望的输出只有\"yes\"或\"no\"。\n",
    "    response = openai_client.chat.completions.create(\n",
    "        model=model,\n",
    "        messages=messages,\n",
    "        max_tokens=1\n",
    "    )\n",
    "    # 从响应中提取内容，即模型的输出。\n",
    "    content = response.choices[0].message.content\n",
    "    # 如果内容为\"yes\"，返回1，表示声明与查询相关；\n",
    "    # 否则返回-1，表示声明与查询不相关。\n",
    "    if content == \"yes\":\n",
    "        return 1\n",
    "    return -1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "从检索结果中提取嵌入向量，然后为生成的查询计算嵌入向量。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "retrieved_embeddings = results['embeddings']\n",
    "query_embeddings = embedding_function(generated_queries)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`adapter_query_embeddings`、`adapter_doc_embeddings`和`adapter_labels`三个空列表将被用于存储适配器查询的嵌入向量、文档的嵌入向量，以及对应的标签。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "adapter_query_embeddings = []\n",
    "adapter_doc_embeddings = []\n",
    "adapter_labels = []"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "遍历生成的查询和每个查询检索到的文档，计算查询和文档的嵌入向量，并使用`evaluate_results`函数评估了每对查询和文档的相关性。对于每个查询和文档的组合，将查询的嵌入向量、文档的嵌入向量和评估结果（作为标签）分别添加到`adapter_query_embeddings`、`adapter_doc_embeddings`和`adapter_labels`列表中。\n",
    "\n",
    "因为使用免费的openAIAPI会出现调用限制等，我们这里使用`time.sleep()`进行减缓请求速度，从而保证因请求过快而被API服务限流。\n",
    "\n",
    "这里也可以使用除openAIAPI以外的API服务。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 15/15 [2:05:28<00:00, 501.89s/it]  \n"
     ]
    }
   ],
   "source": [
    "import time\n",
    "from tqdm import tqdm\n",
    "\n",
    "for q, query in enumerate(tqdm(generated_queries)):\n",
    "    for d, document in enumerate(retrieved_documents[q]):\n",
    "        adapter_query_embeddings.append(query_embeddings[q])\n",
    "        adapter_doc_embeddings.append(retrieved_embeddings[q][d])\n",
    "        adapter_labels.append(evaluate_results(query, document))\n",
    "\n",
    "        time.sleep(30)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "查看新的数据集的长度。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "150"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(adapter_labels)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "得到150个，这是15个查询和10个结果，并且每一个都标有相关性。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用我们的`torch`进行训练我们的嵌入适配器。\n",
    "\n",
    "将我们的数据集转换成`torch tensor`类型数据集，并全部装进`torch`。\n",
    "\n",
    "我们使用这些`Tensor`类型数据训练一个分类模型，该模型预测给定查询和文档对是否相关（即标签为 $1$ 表示相关，$-1$ 表示不相关）。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "adapter_query_embeddings = torch.Tensor(np.array(adapter_query_embeddings))\n",
    "adapter_doc_embeddings = torch.Tensor(np.array(adapter_doc_embeddings))\n",
    "adapter_labels = torch.Tensor(np.expand_dims(np.array(adapter_labels),1))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "创建了一个数据集，数据集封装查询嵌入向量、文档嵌入向量和标签的张量。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "dataset = torch.utils.data.TensorDataset(adapter_query_embeddings, adapter_doc_embeddings, adapter_labels)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 6.3 Setting up the model（设置模型）"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "设置我们的嵌入适配器模型。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用适配器矩阵来更新查询嵌入向量，并计算更新后的查询嵌入向量与文档嵌入向量之间的余弦相似度。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "def model(query_embedding, document_embedding, adaptor_matrix):\n",
    "    updated_query_embedding = torch.matmul(adaptor_matrix, query_embedding)\n",
    "    return torch.cosine_similarity(updated_query_embedding, document_embedding, dim=0)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用均方误差损失来评估模型输出与真实标签之间差异。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "def mse_loss(query_embedding, document_embedding, adaptor_matrix, label):\n",
    "    return torch.nn.MSELoss()(model(query_embedding, document_embedding, adaptor_matrix), label)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "初始化一个适配器矩阵，这个矩阵将用于更新查询嵌入向量或者在模型中执行其他转换任务。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "mat_size = len(adapter_query_embeddings[0])\n",
    "adapter_matrix = torch.randn(mat_size, mat_size, requires_grad=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "建立训练循环，通过最小化损失函数来优化适配器矩阵。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "  0%|          | 0/100 [00:00<?, ?it/s]D:\\Anaconda3\\Lib\\site-packages\\torch\\nn\\modules\\loss.py:535: UserWarning: Using a target size (torch.Size([1])) that is different to the input size (torch.Size([])). This will likely lead to incorrect results due to broadcasting. Please ensure they have the same size.\n",
      "  return F.mse_loss(input, target, reduction=self.reduction)\n",
      "100%|██████████| 100/100 [00:05<00:00, 16.91it/s]\n"
     ]
    }
   ],
   "source": [
    "min_loss = float('inf')\n",
    "best_matrix = None\n",
    "\n",
    "for epoch in tqdm(range(100)):\n",
    "    for query_embedding, document_embedding, label in dataset:\n",
    "        loss = mse_loss(query_embedding, document_embedding, adapter_matrix, label)\n",
    "\n",
    "        if loss < min_loss:\n",
    "            min_loss = loss\n",
    "            best_matrix = adapter_matrix.clone().detach().numpy()\n",
    "\n",
    "        loss.backward()\n",
    "        with torch.no_grad():\n",
    "            adapter_matrix -= 0.01 * adapter_matrix.grad\n",
    "            adapter_matrix.grad.zero_()\n",
    "        "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "打印最佳损失值。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Best loss: 0.3013603091239929\n"
     ]
    }
   ],
   "source": [
    "print(f\"Best loss: {min_loss.detach().numpy()}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "最佳损失值约为0.30，意味我们有了很大的进步。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "接下来，我们看看适配器矩阵是如何影响我们的查询向量的。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用`NumPy`的矩阵乘法函数计算`best_matrix`（一个`NumPy`数组）和`test_vector`（一个`PyTorch`张量）之间的矩阵乘法将结果转换为`NumPy`数组。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_vector = torch.ones((mat_size,1))\n",
    "scaled_vector = np.matmul(best_matrix, test_vector).numpy()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "将上一步保存在`scaled_vector`数组进行绘制条形图。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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mih9Ss72auUbewEAALgTAwAArESIAQAAViLEAAAAKxFiAACAlQgxJzDGaO7cuerVq5c6d+6s3NxcVVRUxLqsDnvuueeUlJQUMtX/MU5JWr58uXw+n9LS0nTZZZeprKwshtW2T2lpqQYPHqytW7eGzG+pt9dee039+/dXamqqLrroIm3fvj2aZbdLuF43bNjQaIwnTpwY8n029bpz505dccUV8nq96tGjh2bMmKH9+/cHl7tpXJvr1U3j+vLLL2vQoEHyer3KyclRQUGBTvxciZvGtLle3TSmJyosLFRSUpJWr14dnBeVMTUIWrhwoenatat54403zN/+9jfTv39/M378+FiX1WGLFi0yw4YNM1988UVwqqioMMYY88orrxiPx2MKCwvNxx9/bEaOHGkGDBhgamtrY1x162zfvt1cd911Ji0tzUgy77//fnBZS739/e9/NykpKebJJ580JSUlZvLkyaZ79+6mqqoqVu00q7le16xZY7KyskLGeN++fcHltvX605/+1MybN8+UlpaaN9980/h8PjNhwgRjjPvGtble3TSuv/vd78xLL71kSktLzdNPP206depkli1bZoxx35g216ubxrTekSNHzJlnnmkkmeeff94YE70xJcT8oLa21nTr1s088cQTwXlr1641kkxZWVkMK+u4/Px8M3ny5LDLLrzwQjNz5szg1//85z+NJLNhw4ZoldchDzzwgLnxxhvNe++91+jC3lJvubm55pprrgku/+6774zH4zHPPfdc9Bpog+Z6feaZZ8zgwYOb/F7bev3Pf/4T8vULL7xgkpOTzeHDh103rs316rZxPdGECRNMbm6uMcZ9x2pDJ/bqxjGdM2eOmTJlSkiIidaY8nLSDz755BN9++23Gj9+fHDe6NGjlZycrOLi4hhW1nEHDhxQt27dGs0/ePCgduzYEdJzv3791LNnT2t6fvTRR/X888+rT58+IfNb09vGjRtDlp988skaPHhw3PbeVK9S02Ncz7ZeG/6V+tTUVNXV1blyXJvqVXLfuJ6otrZWp556qivHtKH6XiX3jenOnTu1fPlyPfnkk8F50RxTQswP6l+r8/l8wXlpaWk67bTTVF5eHquyImL//v1auXKl0tPTNWjQID322GM6duyY9uzZIym0Z0nKycmxpuem/op5S7199913OnjwoFW9N/cX2/fv3693331XnTt3Vv/+/XX//ferurpakqzs9UTGGK1cuVLDhg3TN998I8ld43qiE3v1er2uHNfDhw9r5cqV+vDDD5WXl+fKY7Vew14ldx2rNTU1mjp1qh588MGQP8oczTG18q9YO6G6ulrJycmNfi2y1+tVIBCIUVWRMXfuXD3wwAMKBAJ677339Mgjj+i///2vJk2aJOn7Hk/khp7rTwpN9dbc8m+//TY6RUbQHXfcoV/+8pcyxuiDDz7Qww8/rC+//FKvvvqq1b0eO3ZMd911lzZu3KgtW7a4elwb9iq5b1xTU1MVCASUkZGh5cuX6/zzz9f7778vyX1jGq5XyV1jOmvWLHXr1k333XdfyPxoHqeEmB94PB7V1dXp+PHjSkn5cbPU1NQ02tC2Oe+884L/HzZsmGpra7Vw4UJdd911kqSjR4+GPN4NPdeH0aZ6a2m5bfr27Rv8/5AhQ5SZmambbrpJFRUV1vZaXl6uX/ziFyorK9OGDRs0dOhQffTRR5LcN67hepXcN64lJSWqrKzUxx9/rJkzZ2rXrl269tprJblvTMP1On/+fNeM6YoVK/T666+rpKREycmhL+pE8/zLy0k/yMrKkqSQW1mBQEAVFRVh34Ngs8GDB+vw4cPq0aOHJMnv94cs9/v91vdcP55N9datWzd5PB5X9i59P8aS9O9//9vKXnfv3q1hw4YpPT1dpaWlGj58uCR3jmtTvYZj+7j269dPw4YN0913361Fixbpsccec+WYSuF7PXLkSKPH2Tqm8+bN0/79++Xz+ZSamqrU1FRJ0i233KKpU6dKis6YEmJ+MHjwYKWlpamoqCg4b/PmzUpKStKoUaNiWFnkffTRRzrllFOUnZ2t3r17h/S8e/dulZeXa8yYMTGssOOysrKa7S05OVkjRowIWV7/rMn23qXvxzg5OVk+n8/KXm+44QaNGDFCb7/9trp37x6c78ZxbarXcGwf1xOlpKTIGKPMzEzXjWlD9b3W1tY2WmbrmL777rvatWuXSkpKgpP0fbhZt25d9Ma0Ix+rcpvZs2ebHj16mHXr1pmtW7eafv36mby8vFiX1WF5eXlm7dq1pqSkxDz++OMmNTXVLFy40BhjzOLFi03nzp3NK6+8YrZt22ZGjhxpJk6cGOOK227Pnj2NPnbcUm9vvPGG6dSpk3n66adNSUmJyc3NNeeff745fvx4LFpotXC9zpkzx/zlL38xpaWl5k9/+pM55ZRTzJ133hlcblOvn3/+uZFk1qxZE/K7NL744gtz8OBBV41rS726ZVwrKyvNtGnTzPr1680nn3xiVq9ebXr06GGmTp1qjHHXsdpSr24Z03B0wkesozWmhJgT1NTUmDvvvNNkZGSYU045xdxzzz2mpqYm1mV12IwZM0zXrl2N1+s1F1xwgSksLAwuq6urMw899JDp1q2b6dKli5k6dar57rvvYldsO4W7sLemt6VLl5pevXqZtLQ0c9VVVxm/3x/lytsuXK8PPPCA6d69u0lNTTXnnXeeeeKJJxqdDGzpdfPmzUZS2GnJkiWuGteWenXLuAYCAXP99deb008/3aSmpppzzz3XzJs3L3h+ddOYttSrW8Y0nBNDTLTGNOmHHwwAAGAV3hMDAACsRIgBAABWIsQAAAArEWIAAICVCDEAAMBKhBgAAGAlQgwAALASIQYAAFiJEAMAAKxEiAEAAFYixAAAACsRYgAAgJUIMQAAwEr/H+JhWIQJVC6xAAAAAElFTkSuQmCC",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "plt.bar(range(len(scaled_vector)), scaled_vector.flatten())\n",
    "plt.show()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在这里可以看到我们的每个维度仅由1组成的测试向量被拉伸和挤压，有些已经拉长了很多，而另一些则几乎为零。\n",
    "\n",
    "所以这意味着我们的嵌入适配器基本上已经确定与这些维度相关性。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用`embedding_function`函数为生成的查询计算嵌入向量。\n",
    "\n",
    "使用之前获得的最佳适配器矩阵（`best_matrix`）来调整查询嵌入向量，产生`adapted_query_embeddings`。\n",
    "\n",
    "使用`umap`通过`project_embeddings`函数将原始查询嵌入向量和调整后的查询嵌入向量投影。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 15/15 [00:09<00:00,  1.64it/s]\n",
      "100%|██████████| 15/15 [00:08<00:00,  1.71it/s]\n"
     ]
    }
   ],
   "source": [
    "query_embeddings = embedding_function(generated_queries)\n",
    "adapted_query_embeddings = np.matmul(best_matrix, np.array(query_embeddings).T).T\n",
    "\n",
    "projected_query_embeddings = project_embeddings(query_embeddings, umap_transform)\n",
    "projected_adapted_query_embeddings = project_embeddings(adapted_query_embeddings, umap_transform)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "绘制原始查询嵌入向量、调整后的查询嵌入向量以及数据集嵌入向量的分布图。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.legend.Legend at 0x2cebec6d0d0>"
      ]
     },
     "execution_count": 47,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "\n",
    "plt.figure()\n",
    "plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']  # 设置全局字体为微软雅黑，显示中文\n",
    "plt.scatter(projected_dataset_embeddings[:, 0], projected_dataset_embeddings[:, 1], s=10, color='gray')\n",
    "plt.scatter(projected_query_embeddings[:, 0], projected_query_embeddings[:, 1], s=150, marker='X', color='r', label=\"original\")\n",
    "plt.scatter(projected_adapted_query_embeddings[:, 0], projected_adapted_query_embeddings[:, 1], s=150, marker='X', color='green', label=\"adapted\")\n",
    "\n",
    "plt.gca().set_aspect('equal', 'datalim')\n",
    "plt.title(\"Adapted Queries\")\n",
    "plt.axis('off')\n",
    "plt.legend()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "红色`X`标记表示原始查询嵌入向量的分布，绿色`X`标记表示调整后的查询嵌入向量的分布。\n",
    "\n",
    "可以直接获得关于适配器矩阵调整效果的直观感受，我们的原始查询非常分散，但是我们的调整后的查询更接近某些特定的文档嵌入向量。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 6.4 总结"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "通过本次使用Embedding Adaptors进行自定义查询嵌入向量的处理，从而达到查询结果的增强效果。"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
